<?php
/*
    redirect.php : redirect from one page to another
    source: http://wikkawiki.org/RedirectingPages?show_comments=1#comment_6130

    Copyright 2003  Eric FELDSTEIN
    Copyright 2003  David DELON
    Copyright 2004  Jean Christophe ANDRE
    Copyright 2009  Sebastien CELLES
    Copyright 2010  Tom at klenwell@gmail.com
    This program is free software; you can redistribute it and/or modify

    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License

    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

/*
    Parameters : page : WikiName of the page where you want to redirect
    example : {{redirect page="HomePage"}}
*/

// Defaults
$ActionDefaults = array(
    'show_circular_error'   => 1,
    'usage'                 => '{{redirect page="HomePage"}}',
    'session_key'           => 'wikka_redirect',
    'catch_timeout'         => 5,
    'now'                   => microtime(1)
);

$ActionErrors = array(
    'no_page'       => 'redirect page not set',
    'redirect_self' => 'a page cannot redirect to itself',
    'circular'      => 'circular redirection'
);

// Initialize
$redirect_page = ( isset($vars['page']) ) ? $vars['page'] : '';
$redirect_page = trim($redirect_page);
$page_tag = $this->GetPageTag();
$WikkaRedirectList = array();


// Handle redirect
# Non-show method
if ( $this->GetHandler() != 'show' ) {
    $f = 'redirecting to %s';
    $output = sprintf($f, $redirect_page);
}

# Empty page parameter
elseif ( empty($redirect_page) ) {
    $f = '//%s//: ""<tt>%s</tt>""';
    $output = sprintf($f, $ActionErrors['no_page'], $ActionDefaults['usage']);
}

# Redirect to self
elseif ( strtolower($redirect_page) == strtolower($page_tag) ) {
    $output = sprintf('//%s//', $ActionErrors['redirect_self']);
}

# Proper request
else {
    /* Redirect Guard
      Want to avoid circular redirects, e.g.:
      FooPage -> BarPage -> WtfPage -> FooPage

      Ideally, we would set a cookie on redirect-from page and clear on
      redirect-to page.  But redirect-to page will not call this action.
      So instead, we save the page each redirect comes from for so many
      seconds (set by $ActionDefaults['catch_timeout']). If the same page
      (this page) is redirected to within that time, we print an error
      with a link to the redirect page.
    */
    $k1 = $ActionDefaults['session_key'];
    $k2 = $page_tag;

    $ActiveRedirectSessions = array();
    foreach ( $_SESSION[$k1] as $from_tag => $time ) {
        if ( $ActionDefaults['now'] - $time < $ActionDefaults['catch_timeout'] ) {
            $ActiveRedirectSessions[] = $from_tag;
        }
        else {
            unset($_SESSION[$k1][$from_tag]);
        }
    }

    if ( in_array($from_tag, $ActiveRedirectSessions) ) {
        $age = sprintf('%.2f', $ActionDefaults['now'] - $_SESSION[$k1][$from_tag]);
        $exp = sprintf('%.2f', $ActionDefaults['catch_timeout'] - $age);

        # show error message or hide in comment
        $ef = "%s: redirected from this page %s s ago, auto-redirect block expires in %s s";
        if ( ! $ActionDefaults['show_circular_error'] ) {
            $ef = sprintf('""<!-- %s -->""', $ef);
        }
        $e = sprintf($ef, $ActionErrors['circular'], $age, $exp);

        $f = "page redirects to [[%s]]\n%s";
        $output = sprintf($f, $redirect_page, $e);
    }
    else {
        $_SESSION[$k1][$k2] = microtime(1);
        $this->Redirect($this->Href('', $redirect_page));
    }
}

print $this->Format($output);

?>
